home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d7 / commdrvr.arc / RS232.INC < prev    next >
Text File  |  1988-04-11  |  19KB  |  533 lines

  1.         page
  2. ;***********************************************************
  3. ;**                                                       **
  4. ;**  Device Driver for RS232 communications               **
  5. ;**  Copyright (C) Texas Instruments 1986                 **
  6. ;**  Author: Greg Haley                                   **
  7. ;**                                                       **
  8. ;**  THIS SOURCE CODE MAY BE DISTRIBUTED AND MODIFIED     **
  9. ;**  ONLY IF THE ORIGINAL COPYRIGHT AND AUTHOR CREDITS    **
  10. ;**  REMAIN INTACT.                                       **
  11. ;**                                                       **
  12. ;**  Project Start Date: 09/09/86                         **
  13. ;**                                                       **
  14. ;**  Re: 10/14/86 by Greg Haley                           **
  15. ;**    Added more delays (jmp $+2) for more tolerant      **
  16. ;**    timing. Also increased stacks to 80 words for      **
  17. ;**    Business Pro compatibility.                        **
  18. ;**                                                       **
  19. ;**  Re: 10/15/86 by Greg Haley                           **
  20. ;**    The COMM chip is no longer initialized on every    **
  21. ;**    write request.                                     **
  22. ;**                                                       **
  23. ;**  Re: 10/23/86 by Greg Haley                           **
  24. ;**    Added code to block interrupts while setting up    **
  25. ;**    and restoring the stack.                           **
  26. ;**                                                       **
  27. ;**  Re: 11/07/86 by Greg Haley                           **
  28. ;**    Added option to echo RS232 I/O to the CRT.         **
  29. ;**                                                       **
  30. ;**  Re: 11/13/86 by Greg Haley                           **
  31. ;**    Save SI and AX when calling DOS fast write.        **
  32. ;**    Changed SAR's and SAL's to SHR's and SHL's.        **
  33. ;**    Added keyboard input in parallel with RS232 input. **
  34. ;**                                                       **
  35. ;**  Re: 11/20/86 by Greg Haley                           **
  36. ;**    Modified I/O channel commands so that a more       **
  37. ;**    standard structure could be used, and to make it   **
  38. ;**    easier to add new commands in the future. Also,    **
  39. ;**    all machine dependent code was moved to a seperate **
  40. ;**    file to allow new machines to be added much more   **
  41. ;**    easily.                                            **
  42. ;**                                                       **
  43. ;**  Re: 12/29/86 by Greg Haley                           **
  44. ;**    Fixed bug in XON-XOFF busy handling where XON      **
  45. ;**    was not sent to reset the busy condition.          **
  46. ;**                                                       **
  47. ;***********************************************************
  48.  
  49. cr      equ     13
  50. lf      equ     10
  51. fast_write equ  29h                     ; DOS INT for fast CRT write
  52.  
  53. com1_tbl:                               ;header for device 
  54.         dw      -1
  55.         dw      -1
  56.         dw      1100000000000000B      ; CHAR device with I/O control
  57.         dw      strategy
  58.         dw      entry
  59.         db      'AUX     '        ; Device name to use
  60.  
  61. ;       command jump table
  62. cmdtbl:
  63.         dw      init
  64.         dw      exit
  65.         dw      exit
  66.         dw      ioctl_in
  67.         dw      read
  68.         dw      nd_read
  69.         dw      input_status
  70.         dw      input_flush
  71.         dw      write
  72.         dw      write
  73.         dw      output_status
  74.         dw      exit
  75.         dw      ioctl_out
  76.         dw      exit
  77.         dw      exit
  78.         dw      exit
  79.         dw      exit
  80.  
  81. oldss   dw      0                       ; Old SS reg
  82. oldsp   dw      0                       ; Old SP reg
  83.         dw      80 dup (?)              ; New stack
  84. e_stack label   word
  85. ptrsav  dd      0                       ; DOS cmd block pointer
  86. init_once db    0                       ; flag for init
  87. echo_in db      0                       ; Echo input to console flag
  88. echo_out db     0                       ; Echo output to console flag
  89. key_in    db    0            ; Parallel keyboard input flag
  90. dcw_len    db    0            ; DCW (0) or Length (not 0) mode
  91.  
  92.     page
  93. ;***********************************************************
  94. ;**  Device Driver Entry                                  **
  95. ;***********************************************************
  96. cmdlen  =       0       ;length of this command
  97. unit    =       1       ;sub unit specifier
  98. cmd     =       2       ;command code
  99. status  =       3       ;status
  100. media   =       13      ;media descriptor
  101. trans   =       14      ;transfer address
  102. count   =       18      ;count of blocks or characters
  103. start   =       20      ;first block to transfer
  104.  
  105. ;***********************************************************
  106. ;**  Strategy Routine                                     **
  107. ;***********************************************************
  108. stratp  proc    far
  109.  
  110. strategy:
  111.         mov     word ptr cs:[ptrsav],bx
  112.         mov     word ptr cs:[ptrsav+2],es
  113.         ret
  114.  
  115. stratp  endp
  116.  
  117. ;***********************************************************
  118. ;**  Entry Routine                                        **
  119. ;***********************************************************
  120. entry:
  121.         cli                             ; disable ints
  122.         mov     cs:word ptr oldss,ss
  123.         mov     cs:word ptr oldsp,sp
  124.         mov     sp,cs
  125.         mov     ss,sp
  126.         mov     sp,offset e_stack
  127.         sti                             ; enable ints
  128.         push    si
  129.         push    ax
  130.         push    cx
  131.         push    dx
  132.         push    di
  133.         push    bp
  134.         push    ds
  135.         push    es
  136.         push    bx
  137.  
  138.         lds     bx,cs:[ptrsav]  ;get pointer to i/o packet
  139.  
  140.         mov     cx,word ptr ds:[bx].count    ;cx = count
  141.  
  142.         mov     al,byte ptr ds:[bx].cmd ; al = command  
  143.         cbw
  144.         mov     si,offset cmdtbl
  145.         add     si,ax
  146.         add     si,ax
  147.         cmp     al,16
  148.         ja      cmderr
  149.  
  150.         les     di,dword ptr ds:[bx].trans
  151.  
  152.         push    cs
  153.         pop     ds
  154.         cld
  155.  
  156.         assume  ds:code
  157.  
  158.         jmp     word ptr [si]           ;go do command
  159.  
  160.     page
  161. ;***********************************************************
  162. ;**  Device Driver Exit                                   **
  163. ;***********************************************************
  164. bus$exit:                               ;device busy exit
  165.         mov     ah,00000011b
  166.         jmp     short done
  167.  
  168. cmderr:
  169.         mov     al,3                    ;unknown command error
  170.  
  171. err$exit:
  172.         mov     ah,10000001b            ;mark error return
  173.         jmp     short done
  174.  
  175. exitp   proc    far
  176.  
  177. exit:
  178.         mov     ax,0000000100000000b
  179. done:
  180.         lds     bx,cs:[ptrsav]
  181.         mov     word ptr [bx].status,ax ;mark operation complete
  182.  
  183.         pop     bx
  184.         pop     es
  185.         pop     ds
  186.         pop     bp
  187.         pop     di
  188.         pop     dx
  189.         pop     cx
  190.         pop     ax
  191.         pop     si
  192.  
  193. ; restore stack
  194.         cli                             ; disable ints
  195.         mov     ss,cs:word ptr oldss
  196.         mov     sp,cs:word ptr oldsp
  197.         sti                             ; enable ints
  198.  
  199.         ret                        ;restore regs and return
  200. exitp   endp
  201.  
  202.     page
  203. ;***********************************************************
  204. ;**  Write Routine                                        **
  205. ;**                                                       **
  206. ;**  ES:DI contain xfer adrs on entry                     **
  207. ;**  CX contains num chars to write                       **
  208. ;**                                                       **
  209. ;**                                                       **
  210. ;***********************************************************
  211. write   proc    near
  212.         push    es                      ; Move pointer to DS:SI
  213.         pop     ds
  214.         mov     si,di
  215.  
  216.         mov     dx,cs:word ptr send_buffer ; xmit port
  217.  
  218. send_chars:
  219.         lodsb                           ; al now has char
  220.  
  221.         cmp     cs:byte ptr echo_out,0  ; Echo output on?
  222.         jz      no_echo_out             ; No, skip
  223.         push    si
  224.         push    ax
  225.         int     fast_write              ; Yes, echo to console
  226.         pop     ax
  227.         pop     si
  228. no_echo_out:
  229.  
  230. write_1:
  231.         cmp     cs:byte ptr t_busy,0    ; Is device busy?
  232.         jne     write_1                 ;  Yes, loop again
  233. x_busy:
  234.         cmp     cs:byte ptr xmit_busy,0 ; Is transmitter busy?
  235.         jne     x_busy                  ; Yes, wait for it
  236.         out     dx,al
  237.         mov     cs:byte ptr xmit_busy,1 ; We're busy now
  238.         loop    send_chars              ; look for more chars
  239.  
  240.         jmp     exit
  241. write   endp
  242.  
  243.     page
  244. ;***********************************************************
  245. ;**  Non Destructive Read Routine                         **
  246. ;**                                                       **
  247. ;**  On entry, ES points to buffer segment                **
  248. ;***********************************************************
  249. nd_read         proc    near
  250.         mov     di,13                   ; point to byte buffer
  251.  
  252.     cmp    cs:byte ptr key_in,0    ; Look for keyboard input?
  253.     jz    nd_read_0        ; No, skip
  254.  
  255.         push    cx
  256.         push    di
  257.         call    k_ready                 ; Is a char waiting?
  258.         pop     di
  259.         pop     cx
  260.         jz      nd_read_0               ; No, skip
  261.  
  262.     stosb                ; Yes, store it
  263.         jmp     exit                    ; We're done
  264.  
  265. nd_read_0:
  266.         cmp     cs:word ptr rq_len,0    ; Any chars in receive buffer?
  267.         jnz     nd_read_1               ; Yes, continue
  268.         mov     ah,00000011b            ; Set busy & done
  269.         jmp     done                    ; We're done
  270.  
  271. nd_read_1:
  272.         mov     bx,offset rqueue        ; Get queue ptr
  273.         mov     dx,cs:word ptr rq_tail
  274.         add     bx,dx                   ; point at char
  275.         mov     al,byte ptr[bx]         ; al now has char
  276.  
  277.         cmp     cs:byte ptr echo_in,0   ; Echo input on?
  278.         jz      no_echo_in              ; No, skip
  279.         push    si
  280.         push    ax
  281.         int     fast_write              ; Yes, echo to console
  282.         pop     ax
  283.         pop     si
  284. no_echo_in: 
  285.  
  286.         stosb                           ; store char in buffer
  287.         jmp     exit
  288. nd_read         endp
  289.  
  290.     page
  291. ;***********************************************************
  292. ;**  Get Input Status                                     **
  293. ;***********************************************************
  294. input_status    proc    near
  295.     cmp    cs:byte ptr key_in,0    ; Look for keyboard input?
  296.     jz    in_stat_0        ; No, skip
  297.  
  298.     call    k_ready            ; Is a char waiting?
  299.         jnz     xit_in_stat             ; Yes, exit
  300.  
  301. in_stat_0:
  302.         cmp     cs:word ptr rq_len,0    ; Any chars in receive buffer?
  303.         jnz     xit_in_stat             ; Yes, continue
  304.         mov     ah,00000011b            ; No, set busy & done
  305.         jmp     done                    ; We're done
  306.  
  307. xit_in_stat:
  308.         jmp     exit                    ; Normal exit code
  309. input_status    endp
  310.  
  311.     page
  312. ;***********************************************************
  313. ;**  Flush Input Buffer                                   **
  314. ;***********************************************************
  315. input_flush     proc    near
  316.         mov     cs:word ptr rq_head,0   ; Head = 0
  317.         mov     cs:word ptr rq_tail,0   ; Tail = 0
  318.         mov     cs:word ptr rq_len,0    ; make queue length 0
  319.         jmp     exit                    ; Normal exit code
  320. input_flush     endp
  321.  
  322.     page
  323. ;***********************************************************
  324. ;**  Get Output Status                                    **
  325. ;***********************************************************
  326. output_status   proc    near
  327.         cmp     cs:byte ptr t_busy,0    ; Are we busy?
  328.         je      xit_out_stat            ; No, continue
  329.         mov     ah,00000011b            ; Set busy & done
  330.         jmp     done                    ; We're done
  331.  
  332. xit_out_stat:
  333.         jmp     exit                    ; Normal exit code
  334. output_status   endp
  335.  
  336.     page
  337. ;***********************************************************
  338. ;**  Read Routine                                         **
  339. ;**                                                       **
  340. ;**  ES:DI contain xfer adrs on entry                     **
  341. ;**  CX contains num chars requested                      **
  342. ;***********************************************************
  343. read    proc    near
  344.     cmp    cs:byte ptr key_in,0    ; Look for keyboard input?
  345.     jz    read_0             ; No, skip
  346.  
  347.         push    cx
  348.         push    di
  349.         call    k_ready                 ; Is a char waiting?
  350.         pop     di
  351.         pop     cx
  352.         jz      read_0                  ; No, skip
  353.  
  354.     mov    cx,1
  355.         call    update_count
  356.         push    di
  357.     call    k_read            ; Get char from keyboard
  358.         pop     di
  359.  
  360.     stosb
  361.         jmp     exit                    ; We're done
  362.  
  363. read_0:
  364.         mov     ax,cs:word ptr rq_len   ; Any chars in recv buffer?
  365.         or      ax,ax
  366.         jnz     read_1                  ; Yes, continue
  367.         xor     cx,cx                   ; No, return 0 chars received
  368.         call    update_count
  369.         jmp     exit                    ; We're done
  370.  
  371. read_1:
  372. ; figure out how many chars to get
  373.         cmp     ax,cx                   ; More than DOS buffer?
  374.         jg      read_2                  ;   Yes, CX already has count
  375.         mov     cx,ax                   ;   No, only send what we have
  376.  
  377. read_2:
  378.         call    update_count            ; update chars received
  379.         mov     bx,offset rqueue        ; Get queue ptr
  380.         mov     dx,cs:word ptr rq_tail
  381. read_3:
  382.         add     bx,dx                   ; point at char
  383.         mov     al,byte ptr[bx]         ; al now has char
  384.  
  385.         cmp     cs:byte ptr echo_in,0   ; Echo input on?
  386.         jz      not_echo_in             ; No, skip
  387.         int     fast_write              ; Yes, echo to console
  388. not_echo_in: 
  389.  
  390.         stosb                           ; store char in buffer
  391.         inc     dx
  392.         and     dx,recv_limit           ; wrap if >= limit
  393.         mov     cs:word ptr rq_tail,dx  ; update tail
  394.         dec     cs:word ptr rq_len      ; Adjust queue length
  395.         loop    read_3                  ; Loop again
  396.  
  397. ; reset busy if we can
  398.         cmp     cs:word ptr rq_len,not_busy_len ; Room for more chars?
  399.         jg      read_4                  ; No, skip
  400.         mov     cs:byte ptr r_busy,0    ; Yes, reset busy
  401.     call    send_xon        ; Send XON char if needed
  402. read_4:
  403.  
  404.         jmp     exit
  405. read    endp
  406.  
  407.     page
  408. ;***********************************************************
  409. ;**  Write I/O Control Channel                            **
  410. ;**                                                       **
  411. ;**  ES:DI contain xfer adrs on entry                     **
  412. ;**  CX contains count                                    **
  413. ;***********************************************************
  414. ioctl_out       proc    near
  415.         push    es                      ; Move pointer to DS:SI
  416.         pop     ds
  417.         mov     si,di
  418.  
  419.         cmp     cx,2                    ; Is it a DCW?
  420.         je      ioo_1                   ;  Yes, continue
  421.         cmp     cx,1                    ; Is it a CSB?
  422.         jz      ioo_nc0                 ;  Yes, continue
  423.         jmp     exit                    ;  No, exit
  424.  
  425. ioo_nc0:
  426.         lodsb                           ;  Yes, get the byte
  427.  
  428.     push    cs            ; DS = CS
  429.     pop    ds
  430.  
  431.     mov    ah,al                ;  Update echo output
  432.         and     ah,00100000b
  433.         mov     echo_out,ah
  434.  
  435.     mov    ah,al                ;  Update echo input
  436.         and     ah,01000000b
  437.         mov     echo_in,ah
  438.  
  439.     mov    ah,al                ;  Update keyboard input
  440.         and     ah,10000000b
  441.         mov     key_in,ah
  442.  
  443.     mov    ah,al                ;  Update DCW/LEN mode
  444.         and     ah,00000100b
  445.         mov     dcw_len,ah
  446.  
  447.         test    al,00000001b            ;  Drop RS232 signals?
  448.         jnz     ioo_nc1                 ;  No, skip
  449.         call    de_init                 ;  Yes, disconnect
  450.         mov     byte ptr dcw_len,0     ; Reset to DCW mode
  451. ioo_nc1:
  452.  
  453.         test    al,00000010b            ;  Flush input buffer?
  454.         jz      ioo_nc2                 ;  No, skip
  455.     jmp    input_flush        ;  Yes, go flush it
  456. ioo_nc2:
  457.  
  458.         jmp     exit                    ;  exit
  459. ioo_1:
  460.         lodsw                           ; get DCW in AX
  461.  
  462. ; make ds = cs
  463.         push    cs
  464.         pop     ds
  465.  
  466. ; check for serial device
  467.         test    ah,80h                  ; Serial device?
  468.         jnz     ioo_2                   ;  Yes, continue
  469.         jmp     exit                    ;  No, exit
  470. ioo_2:
  471.  
  472.     call    set_dcw            ; Go set DCW
  473.  
  474.         mov     word ptr dcw,ax         ; Save new DCW
  475.         call    init_comm               ; init comm chip
  476.         jmp     exit
  477.  
  478. ioctl_out       endp
  479.  
  480.     page
  481. ;***********************************************************
  482. ;**  Read I/O Control Channel                             **
  483. ;**                                                       **
  484. ;**  ES:DI contain xfer adrs on entry                     **
  485. ;***********************************************************
  486. ioctl_in        proc    near
  487.         cmp     cx,2                    ; Is it a word?
  488.         je      is_2byte                ;  Yes, go get it
  489.         cmp     cx,1                    ; Is it a byte?
  490.         jne     ioi_xit                 ;  No, exit
  491.  
  492.     xor    al,al            ; Clear status byte
  493.         or      al,cs:byte ptr m_stat   ; Update current modem status
  494.     or    al,cs:echo_out        ; Update echo output
  495.     or    al,cs:echo_in         ; Update echo input
  496.     or    al,cs:key_in          ; Update keyboard input
  497.         stosb                           ; and pass it to DOS
  498.         jmp     exit
  499.  
  500. is_2byte:
  501.     cmp    cs:byte ptr dcw_len,0    ; DCW mode?
  502.     jz     ioi_1            ; Yes, get DCW
  503.  
  504.     mov    ax,cs:rq_len        ; No, get receive queue length
  505.     jmp    short ioi_2
  506.  
  507. ioi_1:
  508.         mov     ax,cs:dcw               ; Get DCW
  509. ioi_2:
  510.         stosw                           ; and pass it to DOS
  511.  
  512. ioi_xit:
  513.         jmp     exit
  514. ioctl_in        endp
  515.  
  516.     page
  517. ;***********************************************************
  518. ;**  Return Number of Chars Processed                     **
  519. ;**                                                       **
  520. ;**  CX contains number of characters processed           **
  521. ;***********************************************************
  522. update_count    proc near
  523.         push    ds
  524.         push    bx
  525.  
  526.         lds     bx,cs:[ptrsav]  ;get pointer to i/o packet
  527.         mov     word ptr ds:[bx].count,cx    ;cx = count
  528.  
  529.         pop     bx
  530.         pop     ds
  531.         ret
  532. update_count    endp
  533.